<template>
	<view class="content">
		<view v-if="type=='line'&&textInside==true">
			<view class="flex-row items-center">
				<view class="progress-line-outer flex-row items-center" :style="{height:strokeWidth+'px'}">
					<view class="progress-line-inner"
						:style="{width:percentage+'%',backgroundColor:color,height:strokeWidth+'px'}"></view>
					<text class="progress-val" :style="{color:textColor}">{{percentage}}%</text>
				</view>
			</view>
		</view>
		<view v-else-if="type=='line'&&textInside==false">
			<view class="flex-row items-center">
				<view class="progress-line-out-outer flex-row items-center" :style="{height:strokeWidth+'px'}">
					<view class="progress-line-out-inner"
						:style="{width:percentage+'%',backgroundColor:color,height:strokeWidth+'px'}"></view>
				</view>
				<text class="progress-val" :style="{color:textColor}">{{percentage}}%</text>
			</view>
		</view>

		<view v-else-if="type=='circle'" class="canvas-container">
			<canvas :style="{ 
			        width: width + 'px', 
			        height: width + 'px',
			        position: 'absolute',
			        left: '-99999px' // 隐藏原始canvas
			      }" canvas-id="canvas" id="canvas"></canvas>

			<image :src="tempImagePath" :style="{
			               width: width + 'px',
			               height: width + 'px',
			               display: tempImagePath ? 'block' : 'none'
			             }" />
		</view>
	</view>
</template>
<script>
	export default {
		props: {
			type: {
				type: String,
				default: 'circle'
			},
			textInside: {
				type: Boolean,
				default: false
			},
			percentage: {
				type: Number,
				default: 30
			},
			width: {
				type: Number,
				default: 150
			},
			color: {
				type: String,
				default: '#27b5ff'
			},
			text: {
				type: String,
				default: ''
			},
			textColor: {
				type: String,
				default: '#555'
			},
			textSize: {
				type: Number,
				default: 18
			},
			strokeWidth: {
				type: Number,
				default: 10
			},
			strokeLinecap: {
				type: String,
				default: 'round'
			},
		},
		data() {
			return {
				//textInside:'true',  //进度条显示文字内置在进度条内（只在 type=line 时可用）context:null,

				rad: Math.PI / 3 * 5 / 100, //绘制的为300度的圆
				format: '', //指定进度条文字内容
				defineBackColor: '', //指定进度条底色（支持 hex 格式）

				status: '', //进度条当前状态	string	success/exception/warning
				//color:'#27b5ff', //进度条背景色（会覆盖 status 状态颜色）	string/function/array
				tempImagePath: '',

			}
		},
		watch: {
			percentage(newVal) {
				if (this.type === 'circle') {
					this.$nextTick(() => {
						this.drawCanvas().catch(console.error);
					});
				}
			}
		},
		mounted() {

			//const ctx = wx.createCanvasContext('canvas'); //在pages中
			//canvas组件注册无效，这个因为createCanvasContext方法在page页面默认传了一个this，在组件里面需要手动传this。同时生成画布的时候wx.canvasToTempFilePath也要传入this,如下面的代码
			if (this.type === 'circle') {
				// 强制重新创建上下文
				this.context = uni.createCanvasContext('canvas', this);
				// 初始绘制
				this.drawCanvas().catch(console.error);
			}
		},
		// watch: {
		// 	percentage(newVal, old) {
		// 		if (newVal) {
		// 			this.reload(newVal)
		// 		}
		// 	}
		// },
		methods: {
			async convertCanvasToImage() {
				try {
					const res = await uni.canvasToTempFilePath({
						canvasId: 'canvas',
						fileType: 'png',
						quality: 1,
						destWidth: this.width * 2, // 提高输出分辨率
						destHeight: this.width * 2
					}, this);

					this.tempImagePath = res.tempFilePath;
					return true;
				} catch (err) {
					console.error('Canvas转换失败:', err);
					return false;
				}

			},
			reload(val) {
				setTimeout(() => {
					this.drawJian(val)
				}, 500)

			},
			draw(val) {
				// this.percentage+=30
				// if(this.percentage>99){
				// 	this.percentage = 100
				// }
				if (this.type == 'circle') {
					// let context = uni.createCanvasContext('canvas')
					// this.context = context
					// 调用定时器实现动态效果
					if (val != '') {
						//this.drawCanvas(val/100);
					}
				} else if (this.type == 'dashboard') {
					this.drawDashboard(val);
				}
			},
			drawJian(val) {

				if (this.type == 'circle') {

				} else if (this.type == 'dashboard') {
					this.drawDashboard(val);
				}
			},
			async drawCanvas() {
				this.tempImagePath = '';
				// 每次重新获取上下文，而不是使用缓存的this.context
				const context = uni.createCanvasContext('canvas', this);
				const width = this.width;
				const center = width / 2; // 中心点坐标
				const radius = center - this.strokeWidth / 2; // 进度条半径

				// 清空画布
				context.clearRect(0, 0, width, width);

				// 绘制背景圆环
				context.beginPath();
				context.arc(center, center, radius, 0, Math.PI * 2);
				context.setStrokeStyle('#eee');
				context.setLineWidth(this.strokeWidth);
				context.stroke();

				// 绘制进度条（修正角度计算）
				const startAngle = -Math.PI / 2; // 起始角度12点方向
				const endAngle = startAngle + (Math.PI * 2 * this.percentage / 100);

				context.beginPath();
				context.arc(center, center, radius, startAngle, endAngle);
				context.setStrokeStyle(this.color);
				context.setLineCap(this.strokeLinecap);
				context.stroke();

				// 绘制文字（居中定位）
				context.setFontSize(this.textSize); // 字体大小，样式
				context.setFillStyle(this.textColor); // 颜色
				context.setTextAlign('center'); // 位置
				context.setTextBaseline('middle');
				context.moveTo(center, center); // 文字填充位置
				if (this.text != '') {
					context.fillText(this.percentage + "%", center, center - 4);
					context.setFontSize(9); // 字体大小，样式
					context.setFillStyle('#999999'); // 颜色
					context.fillText(this.text, center, center + 8);
				} else {
					context.fillText(this.percentage + "%", center, center);
				}

				// 确保绘制完成后再转换
				await new Promise(resolve => context.draw(true, resolve));
				await this.convertCanvasToImage();
			},

			// 新增处理方法
			async handleCanvasConversion() {
				await this.$nextTick(); // 等待DOM更新
				if (this.type === 'circle') {
					await this.convertCanvasToImage('canvas');
				} else if (this.type === 'dashboard') {
					await this.convertCanvasToImage('dashboard');
				}
			},

			drawDashboard(cur) {

				let rad = this.rad
				let context = this.context

				context.setFillStyle('#fff'); // 填充内部颜色
				context.rect(0, 0, this.width, this.width)

				let w = this.width / 2 //画布大小
				let outerR = w //外圈半径
				context.clearRect(0, 0, w, w);
				let outerColor = 'rgb(229,233,242)'


				context.save();
				context.beginPath();
				context.setLineWidth(this.strokeWidth)
				var radius = w
				context.setLineCap(this.strokeLinecap)
				context.setStrokeStyle(outerColor)
				context.arc(w, w, outerR - this.strokeWidth, -Math.PI / 180 * 240, Math.PI / 180 * 60, false);
				//**起点，终点，半径，开始点，结束点，是否顺/逆时针**
				context.stroke();
				context.closePath();
				context.restore();

				context.save();
				context.setStrokeStyle(this.color)
				context.setLineWidth(this.strokeWidth)
				context.setLineCap(this.strokeLinecap)

				if (cur > 0) {
					context.beginPath();
					context.arc(w, w, outerR - this.strokeWidth, -Math.PI / 180 * 240, -Math.PI / 180 * 240 + cur * rad,
						false); //用于绘制圆弧context.arc(x坐标，y坐标，半径，起始角度，终止角度，顺时针/逆时针)
					context.stroke();
					context.closePath();
					context.restore();
				}

				//context.save(); //save和restore可以保证样式属性只运用于该段canvas元素
				context.setFillStyle(this.textColor)
				var font_size = this.textSize;
				context.setFontSize(font_size)
				var text_width = context.measureText(cur.toFixed(0) + "%").width;
				context.fillText(cur.toFixed(0) + "%", w - text_width / 2, w + font_size / 2);
				//context.restore();

				context.draw()
			},

		}
	}
</script>
<style lang="scss" scoped>
	.content {
		/* width: 100vw;
		height: 100vh;
		display: flex;
		justify-content: center;
		align-items: center;
		width: 100%; */
		margin: 0rpx auto;
		box-sizing: border-box;

		.progress-line-outer {
			background-color: #eee;
			width: 100%;
			height: 40rpx;
			border-radius: 50rpx;
			margin: 15rpx 0;

			.progress-line-inner {
				height: 40rpx;
				border-radius: 50rpx;
			}

			.progress-val {
				font-size: 26rpx;
				margin-left: -70rpx;
			}
		}

		.progress-line-out-outer {
			background-color: #eee;
			width: calc(100% - 80rpx);
			height: 20rpx;
			border-radius: 50rpx;
			margin: 15rpx 0;

			.progress-line-out-inner {
				height: 20rpx;
				border-radius: 50rpx;
			}
		}

		.progress-val {
			font-size: 28rpx;
			margin-left: 10rpx;
		}
	}

	/** 引入真实项目时，请将以下样式拷贝到全局样式uni.scss中，不需要每个页面都定义 ----start**/
	view,
	image,
	text {
		box-sizing: border-box;
		flex-shrink: 0;
	}

	#app {
		width: 100vw;
		height: 100vh;
	}

	.flex-row {
		display: flex;
		flex-direction: row;
	}

	.flex-col {
		display: flex;
		flex-direction: column;
	}

	.justify-start {
		display: flex;
		justify-content: flex-start;
	}

	.justify-center {
		display: flex;
		justify-content: center;
	}

	.justify-end {
		display: flex;
		justify-content: flex-end;
	}

	.justify-evenly {
		display: flex;
		justify-content: space-evenly;
	}

	.justify-around {
		display: flex;
		justify-content: space-around;
	}

	.justify-between {
		display: flex;
		justify-content: space-between;
	}

	.items-start {
		display: flex;
		align-items: flex-start;
	}

	.items-center {
		display: flex;
		align-items: center;
	}

	.items-end {
		display: flex;
		align-items: flex-end;
	}

	.canvas-container {
		position: relative;
		display: inline-block;
		overflow: hidden;
		/* 防止图片溢出 */
	}

	image {
		background-color: transparent;
		pointer-events: none;
		/* 避免图片遮挡交互 */
	}

	/** 引入真实项目时，请将以下样式拷贝到全局样式uni.scss中，不需要每个页面都定义 ----end**/
</style>